package com.zz.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.zz.common.ESignParameter;
import com.zz.common.EsignHttpResponse;
import com.zz.common.FileTransformation;
import com.zz.common.ZohoRecord;
import com.zz.service.SaleChangeESignService;
import com.zz.utils.*;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ClassPathResource;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.io.*;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;


@Slf4j
@Service
public class SaleChangeESignServiceImpl implements SaleChangeESignService {

    @Autowired
    ZohoRecord zohoRecord;

    @Autowired
    ESignParameter parameter;

    @Autowired
    IncentiveServiceImpl incentiveService;

    // 当前环境
    public static final String environment = ESignParameter.ENVIRONMENT;

    @Override
    public ResultUtil<String> saleChangeSignature(String id, String operationId) {
        log.info("目标医院模块,生成电子签章入参,id = {},operationId = {}", id, operationId);
        ResultUtil<String> resultUtil;
        // crm数据
        List<JSONObject> targetHospitalList = BiologicalApiUtil.getTargetHospital(zohoRecord.getAccessToken(), id);
        if (targetHospitalList.size() > 0) {
            JSONObject targetHospital = targetHospitalList.get(0);
            System.out.println("targetHospital.toJSONString() = " + targetHospital.toJSONString());
            //1 获取accountId
            String accountId;
            resultUtil = generatorAccount(targetHospital);
            if (!resultUtil.getCode().equals(200)) {
                return resultUtil;
            }

            accountId = resultUtil.getData();
            log.info("===== 第一步【获取accountId】 =====");
            log.info("accountId = " + accountId);

            //2 文件doc ——> PDF
            boolean isCheck = false;
            List<JSONObject> userData = CrmApiUtil.getUserDataById(zohoRecord.getAccessToken(), operationId);
            if (!CollectionUtils.isEmpty(userData)) {
                JSONObject user = userData.get(0);
                JSONObject profile = user.getJSONObject("profile");
                if (Objects.nonNull(profile)) {
                    String roleName = profile.getString("name");
                    log.info("当前用户角色名称 = " + roleName);
                    if (roleName.equalsIgnoreCase("省区经理") ||
                            roleName.equalsIgnoreCase("地区经理") ||
                            roleName.equalsIgnoreCase("商务经理") ||
                            roleName.equalsIgnoreCase("商务大区经理") ||
                            roleName.equalsIgnoreCase("系统管理员") ||
                            roleName.equalsIgnoreCase("Administrator")) {
                        isCheck = true;
                    }
                }
            }

            if (isCheck) {
                log.info("===== 第二步【文件doc ——> PDF】=====");
                //确认人名称
                // 代理商
                String fileName = targetHospital.getString("Name");
                fileName += "_目标医院销售指标变更明细";

                fileName = fileName.replace('\\', '-').replace('/', '-').replace(':', '-')
                        .replace('∶', '-').replace('：', '-').replace('*', '-')
                        .replace('"', '-').replace('<', '-').replace('>', '-')
                        .replace('|', '-').replace('?', '-') + ".PDF";


                ResultUtil<String> generatorPDFResult = generatorPDF(targetHospital);
                if (200 == generatorPDFResult.getCode()) {
                    //3 根据关键字获取X、Y
                    log.info("===== 第三步【根据关键字获取X、Y】=====");
                    String fileId = generatorPDFResult.getData();
                    String keyWord = "确认人签字";
                    JSONObject keyWordPosition = ESignApiUtil.getKeyWordPosition(parameter, environment, fileId, keyWord);
                    log.info("搜索关键字坐标接口result = " + keyWordPosition.toJSONString());
                    if (0 == keyWordPosition.getInteger("code")) {
                        JSONArray data = keyWordPosition.getJSONArray("data");
                        List<JSONObject> list = data.toJavaList(JSONObject.class);
                        if (!CollectionUtils.isEmpty(list)) {
                            JSONObject jsonObject = list.get(0);
                            JSONArray positionList = jsonObject.getJSONArray("positionList");
                            List<JSONObject> position = positionList.toJavaList(JSONObject.class);
                            JSONObject jsonObject1 = position.get(0);
                            Integer pageIndex = jsonObject1.getInteger("pageIndex");
                            JSONArray coordinateList = jsonObject1.getJSONArray("coordinateList");
                            List<JSONObject> list1 = coordinateList.toJavaList(JSONObject.class);
                            JSONObject jsonObject2 = list1.get(0);
                            double posxTemp = jsonObject2.getDouble("posx") + 3.5 * 28.346;
                            int posx = (int) posxTemp;
                            double posyTemp = jsonObject2.getDouble("posy") + 0.5 * 28.346;
                            int posy = (int) posyTemp;

                            Map<String, Integer> map = new HashMap<>();
                            map.put("pageIndex", pageIndex);
                            map.put("posx", posx);
                            map.put("posy", posy);

                            //4 一步签署，回调
                            log.info("===== 第四步【一步发起签署】=====");
                            ResultUtil<String> signResult = launchESign(targetHospital, fileName, fileId, map, accountId);
                            if (200 == signResult.getCode()) {
                                log.info("已向客户手机发送短信，等待验证");
                                return ResultUtil.success("已向客户手机发送短信，等待验证");
                            } else {
                                return signResult;
                            }
                        }
                    } else {
                        return ResultUtil.error("请求关键字坐标接口失败");
                    }
                } else {
                    return generatorPDFResult;
                }
            } else {
                return ResultUtil.error("当前用户角色没有权限");
            }
        } else {
            return ResultUtil.error("合同数据" + id + "为空");
        }
        return ResultUtil.success();
    }


    // 生成待签署PDF文件
    public ResultUtil<String> generatorPDF(JSONObject targetHospital) {

        ResultUtil<String> resultUtil = ResultUtil.success();

        List<JSONObject> allAttachmentList = CrmApiUtil.getAttachmentList(zohoRecord.getAccessToken(), targetHospital.getString("id"), "TargetHospital");
        List<JSONObject> attachmentList = allAttachmentList.stream().filter(jsonObject -> jsonObject.getString("File_Name").contains(".doc")).collect(Collectors.toList());


        if (!CollectionUtils.isEmpty(attachmentList)) {
            // 最近创建的一份合同模板，且与合同名称保持一致
            JSONObject attachment = new JSONObject();
            for (JSONObject jsonObject : attachmentList) {
                if (Objects.isNull(attachment.getString("Created_Time"))) {
                    attachment = jsonObject;
                } else {
                    String dataTime = attachment.getString("Created_Time");
                    String jsonTime = jsonObject.getString("Created_Time");
                    // 合同名称
                    String contractName = targetHospital.getString("Name");
                    contractName = ContractUtil.getContractName(contractName);
                    if (DateUtil.dateCompare(dataTime, jsonTime) && jsonObject.getString("File_Name").contains(contractName)
                    ) {
                        attachment = jsonObject;
                    }
                }
            }
            //// 存储文件id与e签宝id对应关系
            //String attachmentId = attachment.getString("id");
            //log.info("最新附件的id = " + attachmentId);
            //String propId = checkIsPush(attachmentId);
            //if (StringUtils.isNotBlank(propId)) { // 文件已经推送过e签宝，直返返回e签宝的fileId
            //    log.info("该文件已经推送过e签宝");
            //    return ResultUtil.success(propId);
            //} else {

            InputStream attachmentStream = CrmApiUtil.downloadAttachmentByName(zohoRecord.getAccessToken(), targetHospital.getString("id"), attachment.getString("id"), "TargetHospital");
            if (Objects.nonNull(attachmentStream)) {

                String filePath = FileUtil.getRelativeResourceFilePath();
                String fileName = DateUtil.getToday() + "_temp_" + ESignEncryptionUtil.generateSuffix() + ".doc";
                String fileFullPath = filePath + File.separator + fileName;

                //生成文件
                FileUtil.generatorFile(attachmentStream, fileFullPath);
                System.out.println("合同模块生成临时文件 = " + fileFullPath);
                // 1 获取文件上传地址
                JSONObject data = new JSONObject();
                //Content-MD5计算方法
                String fileContentMd5 = ESignEncryptionUtil.getStringContentMD5(fileFullPath);

                String contentType = "application/octet-stream";
                data.put("contentMd5", fileContentMd5);
                data.put("contentType", contentType);
                data.put("convert2Pdf", true);
                String attachFileName = attachment.getString("File_Name");
                attachFileName = attachFileName.replace('\\', '-').replace('/', '-').replace(':', '-').replace('∶', '-').replace('：', '-').replace('*', '-').replace('"', '-').replace('<', '-').replace('>', '-').replace('|', '-').replace('?', '-').replace('+', '-');
                if (!attachFileName.contains(".doc")) {
                    attachFileName += ".doc";
                }

                data.put("fileName", attachFileName);
                data.put("fileSize", attachment.getIntValue("Size"));
                System.out.println("合同模块doc文件名称 = " + attachFileName);
                JSONObject uploadFileUrl = ESignApiUtil.getUploadFileUrl(parameter, environment, data);
                log.info("获取上传文件路径接口result = " + uploadFileUrl.toJSONString());
                if ("0".equals(uploadFileUrl.getString("code"))) {
                    JSONObject jsonData = uploadFileUrl.getJSONObject("data");
                    String uploadUrl = jsonData.getString("uploadUrl");
                    String fileId = jsonData.getString("fileId");

                    // 存储 crm文件id与e签宝id对应关系
                    //saveFileId(attachmentId, fileId, "fileId.properties");
                    //log.info("fileId.properties,存储 crm文件id与e签宝id对应关系,contractId = {},flowId = {}", attachmentId, fileId);

                    // 2 上传文件流（二进制字节流）
                    try {
                        //文件上传
                        EsignHttpResponse uploadFileResponse = ESignApiUtil.uploadFile(uploadUrl, fileFullPath);
                        if (Objects.nonNull(uploadFileResponse)) {
                            JSONObject jsonObject = JSONObject.parseObject(uploadFileResponse.getBody());
                            log.info("上传文件流接口result = " + jsonObject.toJSONString());
                            String code = jsonObject.getString("errCode");
                            if ("0".equals(code)) {
                                log.info("文件上传e签宝成功，状态码 = " + code);
                                //查询文件上传状态
                                boolean isContinue = true; // 是否继续查询文件
                                int time = 0;
                                do {
                                    JSONObject fileUploadStatus = ESignApiUtil.getFileUploadStatus(parameter, environment, fileId);
                                    if ("0".equals(fileUploadStatus.getString("code"))) {
                                        String fileStatus = fileUploadStatus.getJSONObject("data").getString("status");
                                        log.info(String.format("查询文件状态执行第%s次", time + 1));
                                        if ("2".equalsIgnoreCase(fileStatus) || "5".equalsIgnoreCase(fileStatus)) {//查询状态为2或者5代表文件准备完成
                                            log.info("文件已经生成");
                                            isContinue = false;
                                            resultUtil = ResultUtil.success(fileId);
                                        } else {
                                            log.info("文件未准备完成,等待两秒重新查询");
                                            TimeUnit.SECONDS.sleep(2);
                                            time++;
                                        }
                                    }
                                } while (isContinue);

                                // 生成PDF文件后，将合同模块的 签署文档转换状态 改为已完成
                                //JSONObject updateData = new JSONObject();
                                //updateData.put("PDFConvertStatus_c", "已完成"); // 署文档转换状态
                                //CrmApiUtil.updateContractData(targetHospital.getString("id"), updateData);
                            }
                        } else {
                            return ResultUtil.error("e签宝文件流上传失败");
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    // 删除temp文件
                    deleteTempFile();
                } else {
                    return ResultUtil.error("e签宝获取文件路径接口访问失败");
                }
            } else {
                return ResultUtil.error("CRM下载文件失败");
            }
            //}
        } else {
            return ResultUtil.error("该合同不存在附件");
        }
        return resultUtil;
    }

    // 验证 crm文件是否已经推送过e签宝
    public String checkIsPush(String crmFileId) {
        Properties properties = new Properties();
        ClassPathResource classPathResource = new ClassPathResource("fileId.properties");
        InputStream inputStream;
        try {
            inputStream = classPathResource.getInputStream();
            InputStreamReader inputStreamReader = new InputStreamReader(inputStream, StandardCharsets.UTF_8);
            BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
            properties.load(bufferedReader);
            Set<Object> keySets = properties.keySet();
            for (Object obj : keySets) {
                if (crmFileId.equalsIgnoreCase((String) obj)) {
                    return (String) properties.get(obj);
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return "";
    }


    // 存储 crm文件id与e签宝id对应关系
    public void saveFileId(String crmFileId, String eFileId, String fileName) {
        String dir = System.getProperty("user.dir");
        String path = dir + File.separator + "src" + File.separator + "main" + File.separator + "resources" + File.separator + fileName;

        Properties properties = new Properties();
        ClassPathResource classPathResource = new ClassPathResource(fileName);
        InputStream inputStream;
        try {
            inputStream = classPathResource.getInputStream();
            InputStreamReader inputStreamReader = new InputStreamReader(inputStream, StandardCharsets.UTF_8);
            BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
            properties.load(bufferedReader);
            properties.setProperty(crmFileId, eFileId);
            properties.store(new FileWriter(path), null);
        } catch (IOException e) {
            e.printStackTrace();
        }


    }

    public void deleteTempFile() {
        log.info("===== 【删除temp临时文件】 =====");
        // 1 获取所有文件
        List<File> allFile = FileUtil.getAllFile();

        for (File file : allFile) {

            String name = file.getName();
            if (name.contains("_temp_")) {
                if (file.delete()) {
                    log.info(name + " ——> 已经删除");
                }
            }
        }
    }

    public void deletePDFFile() {
        log.info("===== 【删除PDF临时文件】 =====");
        // 1 获取所有文件
        List<File> allFile = FileUtil.getAllFile();

        for (File file : allFile) {

            String name = file.getName();
            if (name.contains("PDF")) {
                if (file.delete()) {
                    log.info(name + " ——> 已经删除");
                }
            }
        }
    }

    @Override
    public ResultUtil<String> generatorAccount(JSONObject targetHospital) {

        List<JSONObject> data = new ArrayList<>();
        // 代理商id
        String personId = "";
        // 代理商
        JSONObject sales_director_c = targetHospital.getJSONObject("Agent_c");
        if (Objects.nonNull(sales_director_c)) {
            String saleId = sales_director_c.getString("id");
            personId = saleId;
            JSONObject jsonData = incentiveService.getSignPeopleData(zohoRecord.getAccessToken(), saleId);
            if (Objects.nonNull(jsonData)) {
                jsonData.put("id", saleId);
                jsonData.put("name", sales_director_c.getString("name"));
                jsonData.put("type", 2);//
                data.add(jsonData);
            }
        }

        // 所有人
        //JSONObject owner = crmContractData.getJSONObject("Owner");
        //if (Objects.nonNull(owner)) {
        //    String saleId = owner.getString("id");
        //    JSONObject jsonData = incentiveService.getSaleDirectorData(zohoRecord.getAccessToken(), saleId);
        //    if (Objects.nonNull(jsonData)) {
        //        jsonData.put("type", 1);//
        //        jsonData.put("id", saleId);
        //        jsonData.put("name", owner.getString("name"));
        //        data.add(jsonData);
        //    }
        //}

        for (JSONObject datum : data) {
            ResultUtil tempResult = incentiveService.callESignAccount(datum);
            if (!tempResult.getCode().equals(200)) {
                return tempResult;
            }
        }

        // 业务签约人的accountId
        List<JSONObject> basicFile = BiologicalApiUtil.getBasicFile(zohoRecord.getAccessToken(), personId);
        String accountId = basicFile.get(0).getString("accountId_c");
        return ResultUtil.success(accountId);
    }

    /**
     * 一步发起签署 合同
     *
     * @param targetHospital 目标医院数据
     * @param fileName       文件名称
     * @param fileId         e签宝文件id
     * @param keywordsPosMap 关键字坐标
     * @param accountId      e签宝的账户id
     */
    public ResultUtil<String> launchESign(JSONObject targetHospital, String fileName, String fileId, Map<String, Integer> keywordsPosMap, String accountId) {

        // 实名认证方式
        String personAvailableAuthTypes_c = targetHospital.getString("personAvailableAuthTypes_c");
        // 意愿认证
        String willTypes_c = targetHospital.getString("willTypes_c");
        // 省区经理
        //JSONObject bizProvinceManager_c = targetHospital.getJSONObject("BizProvinceManager_c");
        //String provinceId = bizProvinceManager_c.getString("id");
        // 合同所有人，取商务经理字段
        //String ownId = "";
        //JSONObject owner = targetHospital.getJSONObject("CommercialManager_c");
        //if (Objects.nonNull(owner)) {
        //    ownId = owner.getString("id");
        //}

        //签约人名称
        //String agentName = "";
        //String agentId = "";
        //// 客户/业务签约人
        //JSONObject agents_c = crmContractData.getJSONObject("Agents_c");
        //if (Objects.nonNull(agents_c)) {
        //    agentName = agents_c.getString("name");
        //    agentId = agents_c.getString("id");
        //}

        // 请求参数
        // 一、flowInfo 类型：object 本次签署流程的基本信息
        Map<String, Object> flowInfo = new HashMap<>();
        flowInfo.put("businessScene", fileName);
        flowInfo.put("autoArchive", true);//是否自动归档
        flowInfo.put("autoInitiate", true);//是否自动开启,流程开启后才能发送短信通知)

        //flowConfigInfo  本次签署流程的任务信息配置
        Map<String, Object> flowConfigInfo = new HashMap<>();
        //flowConfigInfo.put("noticeDeveloperUrl", "http://81.70.161.35:8088/sale/saleChangeCallBack"); // 回调地址
        flowConfigInfo.put("noticeDeveloperUrl", "http://118.24.38.25:8088/sale/saleChangeCallBack"); // 回调地址
        flowConfigInfo.put("noticeType", "1"); // 签署通知方式 短信
        flowConfigInfo.put("signPlatform", "1"); // 签署平台 H5网页版方式进行签署

        //flowConfigInfo.put("willTypes", "CODE_SMS");
        //flowConfigInfo.put("redirectUrl", 1);
        //String[] psn = new String[]{"PSN_TELECOM_AUTHCODE"};
        String psnAuthTypes = StringUtils.isBlank(personAvailableAuthTypes_c) ? "PSN_TELECOM_AUTHCODE" : personAvailableAuthTypes_c;
        psnAuthTypes = TransferUtil.transferTrueName(psnAuthTypes);
        String[] psn = psnAuthTypes.split(",");
        flowConfigInfo.put("personAvailableAuthTypes", psn);

        flowInfo.put("flowConfigInfo", flowConfigInfo);

        //二、signers  array  签署方信息
        List<Map<String, Object>> signersList = new ArrayList<>();
        Map<String, Object> signers = new HashMap<>();
        signers.put("platformSign", false);
        signers.put("signOrder", 1);
        //signerAccount object 签署方账号信息
        Map<String, Object> signerAccount = new HashMap<>();
        signerAccount.put("signerAccountId", accountId);
        signerAccount.put("noticeType", 1);

        String wtsTemp = StringUtils.isBlank(willTypes_c) ? "CODE_SMS" : willTypes_c;
        wtsTemp = TransferUtil.transferWill(wtsTemp);
        String[] wts = wtsTemp.split(",");

        List<String> willTypes = new ArrayList<>();
        Collections.addAll(willTypes, wts);
        signerAccount.put("willTypes", willTypes);
        signers.put("signerAccount", signerAccount);

        //signfields array 签署方的签署区列表数据
        List<Map<String, Object>> signfieldsList = new ArrayList<>();
        Map<String, Object> signfields = new HashMap<>();
        signfields.put("assignedPosbean", true);   //是否固定指定的签署区位置
        signfields.put("autoExecute", false);
        signfields.put("fileId", fileId);
        signfields.put("sealType", 0); // 手绘签名
        signfields.put("signType", 1);//签署类型，0-不限，1-单页签署，2-骑缝签署
        Map<String, Object> posBean = new HashMap<>();
        posBean.put("posPage", keywordsPosMap.get("pageIndex").toString());
        posBean.put("posX", keywordsPosMap.get("posx"));
        posBean.put("posY", keywordsPosMap.get("posy"));
        signfields.put("posBean", posBean);
        signfieldsList.add(signfields);

        signers.put("signfields", signfieldsList);

        signersList.add(signers);

        //三、docs array 待签署文件信息
        List<Map<String, Object>> docsList = new ArrayList<>();
        Map<String, Object> docs = new HashMap<>();
        docs.put("fileId", fileId);
        docs.put("fileName", fileName);
        docs.put("encryption", 0);
        docsList.add(docs);

        //四、copiers 抄送人列表 注：抄送人指不参与签署但需要查看签署文件的人，签署流程归档后抄送人收到通知。
        List<Map<String, Object>> copiersList = new ArrayList<>();
        //if (provinceId.equals(ownId)) {
        //    Map<String, Object> cp1 = new HashMap<>();
        //    cp1.put("copierAccountId", provinceId);
        //    cp1.put("copierIdentityAccountType", 0);
        //    copiersList.add(cp1);
        //}
        //if (!provinceId.equals(ownId) && accountId != null) {
        //    Map<String, Object> cp2 = new HashMap<>();
        //    cp2.put("copierAccountId", accountId);
        //    cp2.put("copierIdentityAccountType", 0);
        //    copiersList.add(cp2);
        //}
        String contractOwnId = targetHospital.getJSONObject("shareuser").getString("id"); // todo shareuser
        // 用这个ownid去【用户信息】模块查询【accountId】
        List<JSONObject> userInfoSearch = BiologicalApiUtil.getUserInfoSearch(zohoRecord.getAccessToken(), contractOwnId);
        if (userInfoSearch.size() > 0) {
            JSONObject jsonObject = userInfoSearch.get(0);
            String signAccountId = jsonObject.getString("Sign_Account_ID");
            Map<String, Object> cp = new HashMap<>();
            cp.put("copierAccountId", signAccountId);
            cp.put("copierIdentityAccountType", 0);
            copiersList.add(cp);
        }

        //总参数
        Map<String, Object> flowMap = new HashMap<>();
        flowMap.put("flowInfo", flowInfo);
        flowMap.put("signers", signersList);
        flowMap.put("docs", docsList);
        if (copiersList.size() > 0) {
            flowMap.put("copiers", copiersList);
        }

        JSONObject updateData = new JSONObject();
        updateData.put("EsignSendTime_c", DateUtil.getTodayHMByT()); // 发送电子签名时间
        JSONObject parameter = new JSONObject(flowMap);
        log.info("一步发起签署接口parameter = " + parameter.toJSONString());
        JSONObject jsonObject = ESignApiUtil.launchESign(this.parameter, environment, parameter);
        log.info("一步发起签署接口result = " + jsonObject.toJSONString());
        if (0 == jsonObject.getInteger("code")) {
            //{"code":0,"data":{"flowId":"f78d199fb54c4022b74fd2b7a9f09772"},"message":"成功"}
            JSONObject data = jsonObject.getJSONObject("data");
            String flowId = data.getString("flowId");
            updateData.put("flowId_c", flowId); // 签署流程id
            //updateData.put("EsignStatus_c", "已发送"); // 签署状态

            // 实名认证方式
            //String psnStr = TransferUtil.transferTrueNameString(psn);
            //updateData.put("personAvailableAuthTypes_c", psnStr);

            // 意愿认证
            //String willStr = TransferUtil.transferWillString(wts);
            //updateData.put("willTypes_c", willStr);

            String targetHospitalId = targetHospital.getString("id");
            //修改目标医院数据
            CrmApiUtil.updateTargetData(targetHospitalId, updateData);

            return ResultUtil.success(flowId);
        } else {
            return ResultUtil.error(jsonObject.toJSONString());
        }
    }


    @Override
    @SneakyThrows
    @Async
    public void saleChangeCallBack(String json) {
        JSONObject jsonObject = JSONObject.parseObject(json);
        String targetHospitalId = "";
        // 认证结束
        if ("SIGN_FLOW_FINISH".equals(jsonObject.getString("action")) &&
                "2".equals(jsonObject.getString("flowStatus"))) {
            log.info("===== 第五步【流程文档下载】=====");
            String flowId = jsonObject.getString("flowId");
            log.info("flowId = " + flowId);
            JSONObject downloadFileResult = ESignApiUtil.downloadFile(parameter, environment, flowId);
            log.info("流程文档下载接口result = " + downloadFileResult.toJSONString());
            // {"code":0,"data":{"docs":[{"fileName":"zb盐酸纳美芬注射液1ml-0.1mg - 5支-盒.PDF","fileUrl":"https://esignoss.esign.cn/1111563786/f12a39af-cc13-4b77-977d-b64721348c6b/%E5%BC%A0%E6%96%8C%E7%9B%90%E9%85%B8%E7%BA%B3%E7%BE%8E%E8%8A%AC%E6%B3%A8%E5%B0%84%E6%B6%B21ml-0.1mg%20-%205%E6%94%AF-%E7%9B%92.PDF?Expires=1677221169&OSSAccessKeyId=LTAI4G23YViiKnxTC28ygQzF&Signature=LJafAn5nOyMFgbKsvLgzMpX7f5w%3D","fileId":"64122458c9dd47389f19e66d0bae3ce4"}]},"message":"成功"}
            if (0 == downloadFileResult.getInteger("code")) {
                JSONObject data = downloadFileResult.getJSONObject("data");
                JSONArray docs = data.getJSONArray("docs");
                List<JSONObject> list = docs.toJavaList(JSONObject.class);
                JSONObject temp = list.get(0);
                String fileName = temp.getString("fileName");
                String fileUrl = temp.getString("fileUrl");
                //String fileId = temp.getString("fileId");

                String filePath = FileUtil.getRelativeResourceFilePath();
                String fileFullPath = filePath + File.separator + fileName;

                try {
                    boolean boo = FileTransformation.downLoadFileByUrl(fileUrl, fileFullPath);
                    if (boo) {
                        log.info("文件生成成功");
                    } else {
                        log.info("文件生成失败");
                    }

                    // 根据flowId查目标医院id
                    String searchUrl = "https://www.zohoapis.com.cn/crm/v3/TargetHospital/search?criteria=(flowId_c:equals:" + flowId + ")";
                    List<JSONObject> moduleDataBySearch = CrmApiUtil.getModuleDataBySearch(zohoRecord.getAccessToken(), searchUrl);
                    if (moduleDataBySearch.size() > 0) {
                        targetHospitalId = moduleDataBySearch.get(0).getString("id");
                    }

                    if (StringUtils.isNotBlank(targetHospitalId)) {
                        log.info("根据flowId查到的targetHospitalId = " + targetHospitalId);
                        // 存储到目标医院中的附件,文件流方式
                        String url = "https://www.zohoapis.com.cn/crm/v3/TargetHospital/" + targetHospitalId + "/Attachments";
                        log.info("url = " + url);
                        JSONObject uploadFileResult = HttpUtil.postFileByFileStream(zohoRecord.getAccessToken(), fileFullPath, url);
                        if (uploadFileResult.toJSONString().contains("SUCCESS")) {
                            log.info("附件传送成功");
                            //System.out.println("uploadFileResult.toJSONString() = " + uploadFileResult.toJSONString());
                            //JSONArray tempData = uploadFileResult.getJSONArray("data");
                            //List<JSONObject> tempList = tempData.toJavaList(JSONObject.class);
                            //String fileId = tempList.get(0).getJSONObject("details").getString("id");
                            // 存储合同模块 签署文件ID字段
                            //JSONObject updateData = new JSONObject();
                            //updateData.put("fileId_c", fileId);
                            //CrmApiUtil.updateContractData(targetHospitalId, updateData);

                            // 删除temp文件
                            deleteTempFile();
                        } else {
                            log.info("附件传送失败，{}", uploadFileResult.toJSONString());
                        }
                        // 删除临时文件
                        deletePDFFile();
                    } else {
                        log.info("targetHospitalId查询数据为空");
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }

            if (StringUtils.isNotBlank(targetHospitalId)) {
                // 更新目标医院的 目标医院销售指标变更申请 的 是否签订
                updateSaleTarget(targetHospitalId);
            }

        }
    }

    public void updateSaleTarget(String targetHospitalId) {

        // 1 该目标医院下的目标医院销售指标变更申请
        List<JSONObject> targetList = BiologicalApiUtil.getSaleTargetSaleChangeByBasic(zohoRecord.getAccessToken(), targetHospitalId);
        List<JSONObject> jsonStream = targetList.stream().sorted(Comparator.comparing(s -> s.getDate("Created_Time"))).collect(Collectors.toList());
        JSONObject json = jsonStream.get(jsonStream.size()-1);

        JSONArray jsonData = new JSONArray();
        String id = json.getString("id");
        JSONObject updateJson = new JSONObject();
        updateJson.put("Is_Sign_c", true); // 是否签订
        updateJson.put("id", id);
        jsonData.add(updateJson);

        Map<String, Object> paramsMap = new HashMap<>();
        paramsMap.put("data", jsonData);
        log.info("数据更新：" + new JSONObject(paramsMap));
        String url = "https://www.zohoapis.com.cn/crm/v3/TargetHospitalSaleTargetChange";
        HttpUtil.putDataByHead(zohoRecord.getAccessToken(), url, paramsMap);

    }

}
